Skip to main content

12 对象构造过程

基于对象的 JavaScript

JavaScript 1.0 可以将函数作为构造器,并且在函数中向它的实例(也就是this对象)抄写类声明的那些属性。在早期的面向对象理论里,可以称这个函数为类,这个被创建出来的实例为对象。

类抄写:将类所拥有的属性声明一项一项地抄写到对象上面,这个对象就是 this 引用。

function Car() {
this.name = "Car";
this.color = "Red";
}

var car = new Car();

类与构造器

JavaScript 1.1 支持原型继承,类抄写成为过时的方案。

function Device() {
this.id = 0; // or increment
}

function Car() {
this.name = "Car";
this.color = "Red";
}

Car.prototype = new Device();

var x = new Car();
console.log(x.id);

> x instanceof Device
true

// x = new Car()
x.[[Prototype]] === Car.prototype

// 因为
x.[[Prototype]] === Car.prototype
// 且
Car.prototype = new Device()

// 所以
x.[[Prototype]].[[Prototype]] === Device.prototype
// 对象x是Device()或其子类的一个实例。

ECMAScript 6 之后的类

class AClass {
...
}

类只能用 new 运算来创建,而不能使用“()”来做函数调用。不能对方法做 new 运算。

函数可以简单地分为三个大类:

  1. 类:只可以做 new 运算;
  2. 方法:只可以做调用“( )”运算;
  3. 一般函数:(除部分函数有特殊限制外,)同时可以做 new 和调用运算。

典型的方法在内部声明时,有三个主要特征:

  1. 具有一个名为“主对象[[HomeObject]]”的内部槽;
  2. 没有名为“构造器[[Construct]]”的内部槽;
  3. 没有名为“prototype”的属性。

创建this的顺序问题

  1. 必须在构造器方法(constructor)中显式地使用super()来调用父类的构造过程;
  2. 在上述调用结束之前,是不能使用this引用的。

ECMAScript 6 的类是由父类或祖先类创建this实例的。

用户返回 new 的结果

用户代码可以干涉 new 运算的结果。用户可以通过在构造器函数 / 方法中使用return语句来显式地重置创建出来的this对象实例。